package NWish
{
	import NWish.Interface.IApp;
	
	import NWish.properties.OtherPropertiesTypes;
	
	import flash.events.Event;
	
	public class PropertiesExplorer
	{
		private var _parent:IApp;
		public function get parent(){return _parent;}
		
		private var _window:Window;
		
		public function PropertiesExplorer(parent:IApp)
		{
			//
			_parent = parent;
			
			//
			var menuBar:MenuBar = _parent.getPlugin('MenuBar') as MenuBar;
			menuBar.windowMenu.addMenuItem("&Properties Explorer").addActionListener(_showWindow);
			
			//
			_window = new Window(this);
			_parent.rootSprite.stage.addEventListener(Event.RESIZE, 	_onStageResize);
			_window.show();
			
			//
			_parent.rootSprite.addEventListener(NWEvent.SELSCT_OBJECT,	_window.onSelectObject);
			_parent.rootSprite.addEventListener(NWEvent.MULTI_APPLY,	_window.onMultiApply);
			//_parent.rootSprite.addEventListener(NWEvent.CHANGE_OBJ	ECT,_window.onChangeObject);
			_parent.rootSprite.addEventListener(NWEvent.CLEAR_SCENE,	function () {_window.currObject = null;});
		}
		
		public function init()
		{
			
		}
		
		public function setText(t:String)
		{
			return _window.setText(t);
		}
		public function get currObject()
		{
			return _window.currObject;
		}
		public function set currObject(o)
		{
			_window.currObject = o;
		}
		
		public function setOtherObject(o,type)
		{
			_window.currPropertiesTypes = new OtherPropertiesTypes([type]);
			_window.currObject = o;
		}
		
		private function _showWindow(e:Event)
		{
			_window.show();
		}
		
		private function _onStageResize(event :Event) : void
		{
			_window.x = _parent.rootSprite.stage.stageWidth - _window.width;
			//_window.height = _parent.stage.stageHeight;
		}
		
		
		public function addObject3DPropertiesType(pt)
		{
			_window.addObject3DPropertiesType(pt);
		}
		public function addMaterialPropertiesType(pt)
		{
			_window.addMaterialPropertiesType(pt);
		}
		public function addAnimatorPropertiesType(pt)
		{
			_window.addAnimatorPropertiesType(pt);
		}
		
	}
}


//
import NWish.Interface.ILogger;

import NWish.Misc;
import NWish.NWEvent;
import NWish.PropertiesExplorer;
import NWish.json.Json;
import NWish.properties.*;

import away3d.cameras.Camera3D;
import away3d.core.base.Object3D;

import flash.events.Event;

import org.aswing.*;
import org.aswing.border.*;
import org.aswing.colorchooser.*;
import org.aswing.event.AWEvent;
import org.aswing.ext.*;
import org.aswing.geom.*;


class Window extends JFrame
{
	private var _parent			:PropertiesExplorer;
	
	//members define
	private var _panel			:JPanel;
	
	private var _properties		:JTextArea;
	private var _multiApply		:JButton;
	private var _apply			:JButton;
	private var _type			:JComboBox;
	private var _create			:JButton;
	private var _multiCreate	:JButton;
	
	//
	private var _currPropertiesTypes;
	private var _currObject;
	
	private var _buttonGroup:ButtonGroup = new ButtonGroup();
	
	//
	private var _Object3DPropertiesTypes;
	private var _MaterialPropertiesTypes;
	private var _MaterialMethodPropertiesTypes;
	private var _AnimatorPropertiesTypes;
	private var _CustomPropertiesTypes;
	
	public function Window(parent:PropertiesExplorer)
	{
		//
		_parent = parent;
		
		//
		super(null,'Properties Explorer');
		
		//
		setLocationXY(0,15);
		setSize(new IntDimension(265, 700));
		
		//
		_panel = new JPanel();
		_panel.setSize(new IntDimension(250, 660));
		setContentPane(_panel);
		
		//component creation
		var layout0:EmptyLayout = new EmptyLayout();
		_panel.setLayout(layout0);
		
		_properties = new JTextArea();
		_properties.setLocation(new IntPoint(5, 34));
		_properties.setSize(new IntDimension(320, 568 + 16));
		
		_multiApply = new JButton();
		_multiApply.setLocation(new IntPoint(5, 620));
		_multiApply.setSize(new IntDimension(120, 20));
		_multiApply.setText("Multi Apply");
		_multiApply.setEnabled(false);
		
		_apply = new JButton();
		_apply.setLocation(new IntPoint(125, 620));
		_apply.setSize(new IntDimension(120, 20));
		_apply.setText("Apply");
		_apply.setEnabled(false);
		
		_type = new JComboBox();
		_type.setLocation(new IntPoint(5, 642));
		_type.setSize(new IntDimension(100, 22));
		_type.setToolTipText("type");
		_type.setMaximumRowCount(16);
		
		_multiCreate = new JButton();
		_multiCreate.setLocation(new IntPoint(110, 642));
		_multiCreate.setSize(new IntDimension(70, 22));
		_multiCreate.setText("Multi Create");
		_multiCreate.setToolTipText("Multi Create");
		_multiCreate.setEnabled(false);

		_create = new JButton();
		_create.setLocation(new IntPoint(180, 642));
		_create.setSize(new IntDimension(65, 22));
		_create.setText("Create");
		_create.setEnabled(false);
		
		//component layoution
		_panel.append(_properties);
		_panel.append(_multiApply);
		_panel.append(_apply);
		_panel.append(_type);
		_panel.append(_create);
		_panel.append(_multiCreate);
		
		//
		_type.addActionListener(_actionType);
		_create.addActionListener(_actionCreate);
		_multiCreate.addActionListener(_actionMultiCreate);
		_multiApply.addActionListener(_actionMultiApply);
		_apply.addActionListener(_actionApply);

		//
		_Object3DPropertiesTypes = new Object3DPropertiesTypes(_parent.parent,this);
		_MaterialPropertiesTypes = new MaterialPropertiesTypes(_parent.parent,this);
		//_MaterialMethodPropertiesTypes = new MaterialMethodPropertiesTypes(_parent.parent,this,_MaterialPropertiesTypes);
		_AnimatorPropertiesTypes = new AnimatorPropertiesTypes(_parent.parent,this);
		_CustomPropertiesTypes = new CustomPropertiesTypes(_parent.parent,this);

	}
	
	public function get buttonGroup()
	{
		return _buttonGroup;
	}
	
	public function get panel()
	{
		return _panel;
	}
	
	public function setText(t)
	{
		_properties.setText(t);
	}
	public function get currPropertiesTypes()
	{
		return _currPropertiesTypes;
	}
	public function set currPropertiesTypes(pts)
	{
		_currPropertiesTypes = pts;
		_type.setListData(_currPropertiesTypes.types);
		
		if(_currObject)
		{
			currObject = _currObject;
		}
		else
		{
			_type.getEditor().setValue('');
			_create.setEnabled(false);
			_multiCreate.setEnabled(false);
			_properties.setText('');
		}
	}
	
	override public function setVisible(v:Boolean):void
	{
		super.setVisible(v);
		
		if(v)
			currObject = _currObject;
	}
	
	
	public function get scene()
	{
		var away3d = _parent.parent.getPlugin('Away3d');
		if(away3d.view)
			return away3d.view.scene;
		
		return null;
	}
	
	private function showObjectTitle()
	{
		var name = '';
		try
		{
			if(_currObject == null)
			{
				
			}
			else if(_currObject is Array)
			{
				if(_currObject.length == 1)
				{
					name = _currObject[0].name;
					name = '[' + name + ']'; 
				}
				else
				{
					var n :String = _currObject;
					n = n.replace('object ','');
					name = n;
				}
			}
			else
			{
				name = _currObject.name;
				name = '[' + name + ']'; 
			}
		}
		catch(e:*)
		{
			var n :String = _currObject;
			n = n.replace('object ','');
			name = n;
		}
		
		this.setTitle(name + ' Properties Explorer');
		this.setToolTipText(name);
	}
	public function get currObject()
	{
		return _currObject;
	}
	public function set currObject(o)
	{
		_currObject = o;
		
		if(this.isVisible() == false)
			return;

		
		if(_currObject)
		{
			showObjectTitle();
			
			//
			var properties;
			if(_currObject is Array && _currObject.length > 0)
				_currObject = _currObject[0];
			//else
			//	return;
			
			properties = _currPropertiesTypes.getPropertiesType(_currObject);
			
			if(properties)
			{
				_properties.setText(properties.getJSON(_currObject));
				
				_multiCreate.setEnabled(properties.multiCreateEnable);
				
				_apply.setEnabled(true);
				_multiApply.setEnabled(false);
				
				//_type.setSelectedItem(properties);//这函数会调用_actionType,并且重新刷新_properties:JTextArea的内容
				_type.getEditor().setValue(properties);
				return;
			}
			else
			{
				_type.getEditor().setValue('');
				ILogger.log('can not find ' + _currPropertiesTypes + '!',_currObject);
			}
		}

		//
		{
			_properties.setText('');
			_multiCreate.setEnabled(false);
			_apply.setEnabled(false);
			_multiApply.setEnabled(false);
			//_type.setSelectedItem('');
			_type.getEditor().setValue('');
			_create.setEnabled(false);
		}
	}
	
	public function addObject3DPropertiesType(pt)
	{
		_Object3DPropertiesTypes.addPropertiesType(pt);
		currPropertiesTypes = currPropertiesTypes;
	}
	public function addMaterialPropertiesType(pt)
	{
		_MaterialPropertiesTypes.addPropertiesType(pt);
		currPropertiesTypes = currPropertiesTypes;
	}
	public function addAnimatorPropertiesType(pt)
	{
		_AnimatorPropertiesTypes.addPropertiesType(pt);
		currPropertiesTypes = currPropertiesTypes;
	}
	
	private function _actionType(e:AWEvent)
	{
		var type = _type.getSelectedItem();
		
		var json = type.getJSON(null/*,scene*/);
		if(json)
		{
			_properties.setText(json);
			
			_multiCreate.setEnabled(type.multiCreateEnable);
			
			_create.setEnabled(type.createEnable);
		}
		else
		{
			_properties.setText('');
			
			_multiCreate.setEnabled(false);
			
			_create.setEnabled(false);
		}
		
		this._apply.setEnabled(false);
		this._currObject = null;
		this.showObjectTitle();
	}
	
	private function _actionCreate(e:AWEvent)
	{
		var type = _type.getSelectedItem();
		
		var newObj = type.create(_properties.getText(), scene);
		 
		if(newObj is Array)
		{
			if(newObj.length == 0)
			{
				ILogger.log('Multi create error!',newObj);
				return;
			}
			
			currObject = newObj[0];
			
		}
		else
		{
			if(newObj == null)
			{
				ILogger.log('create error!',newObj);
				return;
			}
			currObject = newObj;
		}
		
		//
		_parent.parent.dispatchEvent(new NWEvent(NWEvent.CREATE_OBJECT,newObj))
	}
	
	private function _actionMultiCreate(e:AWEvent)
	{
		var type = _type.getSelectedItem();
		var s = type.getMultiCreateJson();
		
		_properties.appendText(s);
		_properties.scrollToBottomLeft();
	}
	
	private function _actionMultiApply(e:AWEvent)
	{
		var pro_str = _properties.getText();
		var str_pos = pro_str.search(_multiApplyStr);
		
		if(str_pos == -1)
		{
			ILogger.log('Can not find the #MultiApply info');
			return;
		}
		
		//
		var ma = pro_str.substr(str_pos + _multiApplyStr.length);
		var obj_ns = Json.decode( ma );
		
		
		//
		for each(var name in obj_ns)
		{
			var o = Misc.getChildByNameInScene(name,scene);
			if(o)
			{
				var type = _currPropertiesTypes.getPropertiesType(o);
				if(type)
					type.apply(o,pro_str, scene);
				else
					ILogger.log('can not find properties type',o)
			}
			else
			{
				ILogger.log('Can not find the object, name[' + name + ']!')
			}
		}
	}
	
	private function _actionApply(e:AWEvent)
	{
		if(currObject)
		{
			var type = _currPropertiesTypes.getPropertiesType(currObject);
			
			type.apply(currObject,_properties.getText(), scene);
		}
		else
		{
			ILogger.log('please to select object');
		}
	}
	
	
	public function onSelectObject(e:NWEvent)
	{
		currObject = e.objects;
	}
	
	//
	var _multiApplyStr:String = '#Multi Apply';
	var _currType = Object3D;
	public function onMultiApply(e:NWEvent)
	{
		var os;
		if(e.objects is Array)
			os = e.objects;
		else
			os = [e.objects];
			
		var str = '';
		for each(var o in os)
		{
			var name = '';

			if(o is _currType
			&& !(o is Camera3D))
				name += o.name;
			else
				ILogger.log('this object can not use "Multi Apply" !',o)

			
			if(name.length)
			{
				if(str.length)
					str += '\n,';
				
				str += '"';
				str += name;
				str += '"';
			}
		}
		
		if(str)
		{
			var text = _properties.getText();

			var str_pos = text.search(_multiApplyStr);
			if(str_pos != -1)
			{
				text = text.substr(0,str_pos - 1);
				_properties.setText(text);
			}
			
			if(_properties.getText().length)
				_multiApply.setEnabled(true);
			else
				_multiApply.setEnabled(false);
			
			str = '\n' + _multiApplyStr + '\n[\n' + str + '\n]';
			_properties.appendText(str);
			_properties.scrollToBottomLeft();
		}
		else
		{
			ILogger.log('please select more object!')
		}
	}
}




